package com.fxu.jushuitan.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.fxu.framework.biz.util.BizUtil;
import com.fxu.jushuitan.dto.*;
import com.fxu.jushuitan.dto.aftersale.ReceivedRes;
import com.fxu.jushuitan.dto.aftersale.RefundRes;
import com.fxu.jushuitan.dto.goods.SkuQueryReq;
import com.fxu.jushuitan.dto.goods.SkuQueryRes;
import com.fxu.jushuitan.dto.logistic.LogisticReq;
import com.fxu.jushuitan.dto.logistic.LogisticRes;
import com.fxu.jushuitan.dto.order.*;
import com.fxu.jushuitan.dto.purchase.*;
import com.fxu.jushuitan.dto.shop.ShopReq;
import com.fxu.jushuitan.dto.shop.ShopRes;
import com.fxu.jushuitan.dto.supplier.SupplierQueryReq;
import com.fxu.jushuitan.dto.supplier.SupplierQueryRes;
import com.fxu.jushuitan.dto.wms.*;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.*;

/**
 * 聚水潭接口调用工具类
 * @author fangxu
 * @since 2023-07-11
 */
@Slf4j
public class JstRequest {

    // 2023-07-11 还有30天refreshToken过期
    public static void main(String[] args) {
        Integer shopId = 15476271;
//        JstToken jstToken = JstHolder.accessToken("", "");
//        JstToken jstToken = JstHolder.getHolder().accessToken();
//        System.out.println(jstToken);
//        JstToken jstToken = JstHolder.getHolder().refreshToken("99f0ecaaaff84218bf066a00e26518c6");
//        String accessToken = JstTokenHolder.getHolder().getAccessToken();
//        afterSale(jstToken.getAccessToken());
//        partnerQuery("5526cda32fa346f1ae3e22f705115480");
//        inventoryQuery(jstToken.getAccessToken(), 11799048);
//        inventoryUpload(jstToken.getAccessToken());

//        supplierQuery(jstToken.getAccessToken());

//        PageRes<SkuQueryRes> temp = skuQuery(jstToken.getAccessToken(), 1, Collections.singletonList("椰子鸡经典年货版"));
//        System.out.println(temp);
//        PageRes<SkuQueryRes> temp = combineSkyQuery("f0799095137c411c94c064e20949be1a", 1, Collections.singletonList("经典版椰子鸡套餐-A1(测试）"));
//        System.out.println(temp);
        JstConfig config = JstHolder.getConfig("d950543a19cb43e19d2a06ee5a87a133", "1778a6224e6b40099179f2c024fd5941", true);
//        System.out.println(config);
        saleOrderQuery(config, shopId, CollUtil.toList("XS20250603008"));
//        saleOrderQuery(config, shopId, CollUtil.toList("XS20250113324"));
//        saleOrderQuery(config, shopId, CollUtil.toList("XS20250113049"));
//        saleOrderQuery(config, shopId, CollUtil.toList("XS20250102315"));
//        saleOrderQuery(config, shopId, CollUtil.toList("XS20240328175"));
//        saleOrderQuery(config, shopId, CollUtil.toList("XS20250102033"));
//        saleOrderQuery(config, shopId, CollUtil.toList("XS20241230202"));
//        saleOrderQuery(config, shopId, CollUtil.toList("XS20241230203"));
//        saleOrderQuery(config, shopId, CollUtil.toList("XS20241231064"));
//        saleOrderQuery(config, shopId, CollUtil.toList("XS20241217386"));
//        shopQuery("3fe538b16c7a4eda8df2cdeb15fcf722", 1, CollUtil.toList(""));
//        logisticQuery(config, CollUtil.toList("XS20241217386"));
    }

    private static List<String> SPECIAL_STATUSES = CollUtil.toList("Merged", "Split");
    private static List<String> SUCCESS_STATUSES = CollUtil.toList("Sent", "Delivering");
    private static List<String> FAILED_STATUSES = CollUtil.toList("Cancelled", "Delete");
    // 销售订单查询
    public static List<OrderQuerySml> saleOrderQuery(JstConfig config, Integer shopId, List<String> soIds) {
        int page = 1; String accessToken = config.getAccessToken();
        String url = "https://openapi.jushuitan.com/open/orders/single/query";
        String biz = JstBizUtil.toBiz(new OrderQueryReq(page, shopId, soIds, null));
        if (config.isLog()) log.debug("accessToken={},biz={}", accessToken, biz);
        List<OrderQuerySml> list = new ArrayList<>();
        String body = JstHolder.query(accessToken, url, biz, config.getAppKey(), config.getSecret());
        if (config.isLog()) log.debug("body={}", body);
        PageRes<OrderQuerySml> res = RootRes.toPage(body, OrderQuerySml.class, "orders");
        if (res != null) list.addAll(res.getDataList());
        while (res != null && res.hasNextPage()) {
            biz = JstBizUtil.toBiz(new OrderQueryReq(++page, shopId, soIds, null));
            if (config.isLog()) log.debug("accessToken={},biz={}", accessToken, biz);
            body = JstHolder.getHolder().query(accessToken, url, biz);
            if (config.isLog()) log.debug("body={}", body);
            res = RootRes.toPage(body, OrderQuerySml.class, "orders");
            if (res != null) list.addAll(res.getDataList());
        }

        // 合并拆分订单处理
        if (config.isLog()) log.debug("list={}", JSONUtil.toJsonStr(list));
        ListUtil.sortByProperty(list, "oId");
        if (config.isLog()) log.debug("list={}", JSONUtil.toJsonStr(list));
        List<OrderQuerySml> newList = new ArrayList<>();
        for (String soId : soIds) {
            List<OrderQuerySml> finds = BizUtil.filter(list, v -> v.getSoId().equals(soId) || (v.getMergeSoId() != null
                    && v.getMergeSoId().contains(":" + soId)) || (v.get__raw_so_ids__() != null
                    && v.get__raw_so_ids__().stream().anyMatch(rs -> rs.contains(":" + soId))));
            //if (config.isLog()) log.debug("finds={}", JSONUtil.toJsonStr(list));
            if (CollUtil.isNotEmpty(finds) && finds.size() == 1) {
                newList.add(finds.get(0));
                continue;
            }
            OrderQuerySml sml = CollUtil.findOne(finds, v -> v.getSoId().equals(soId) && SUCCESS_STATUSES.contains(v.getStatus()));
            if (sml != null) {
                newList.add(sml);
                continue;
            }
            sml = CollUtil.findOne(finds, v -> v.getSoId().equals(soId) && SPECIAL_STATUSES.contains(v.getStatus()));
            if (sml != null) {
                OrderQuerySml newSml = getLastOne(BizUtil.filter(finds, v -> v.getMergeSoId() != null
                        && v.getMergeSoId().contains(":" + soId) || (v.get__raw_so_ids__() != null
                        && v.get__raw_so_ids__().stream().anyMatch(rs -> rs.contains(":" + soId)))));
                if (newSml != null) {
                    sml.setLogisticsCompany(newSml.getLogisticsCompany());
                    sml.setLId(newSml.getLId());
                    sml.setStatus(newSml.getStatus());
                    sml.setLinkSoId(newSml.getSoId());
                    newList.add(sml);
                } else {
                    sml = CollUtil.findOne(finds, v -> v.getSoId().equals(soId) && FAILED_STATUSES.contains(v.getStatus()));
                    if (sml != null) {
                        newList.add(sml);
                    }
                }
            } else {
                sml = CollUtil.findOne(finds, v -> v.getSoId().equals(soId) && FAILED_STATUSES.contains(v.getStatus()));
                if (sml != null) {
                    newList.add(sml);
                }
            }
        }
        // 查询物流信息
        List<LogisticRes> logisticList = logisticQuery(config, soIds);
        for (OrderQuerySml orderQuerySml : newList) {
            orderQuerySml.setLogistics(BizUtil.filter(logisticList, v -> v.getSoId() != null
                    && ((orderQuerySml.getSoId() != null && v.getSoId().equals(orderQuerySml.getSoId()))
                    || (orderQuerySml.getLinkSoId() != null && v.getSoId().equals(orderQuerySml.getLinkSoId())))));
        }
        if (config.isLog()) System.out.println(JSONUtil.toJsonStr(newList));
        return newList;
    }

    public static OrderQuerySml getLastOne(List<OrderQuerySml> list) {
        if (CollUtil.isEmpty(list)) return null;
        return list.get(list.size() - 1);
    }

    // 物流查询
    public static List<LogisticRes> logisticQuery(JstConfig config, List<String> soIds) {
        int page = 1; String accessToken = config.getAccessToken();
        String url = "https://openapi.jushuitan.com/open/logistic/query";
        String biz = JstBizUtil.toBiz(new LogisticReq(page, soIds));
        if (config.isLog()) log.debug("accessToken={},biz={}", accessToken, biz);
        List<LogisticRes> list = new ArrayList<>();
        String body = JstHolder.query(accessToken, url, biz, config.getAppKey(), config.getSecret());
        if (config.isLog()) log.debug("body={}", body);
        PageRes<LogisticRes> res = RootRes.toPage(body, LogisticRes.class, "orders");
        if (res != null) list.addAll(res.getDataList());
        while (res != null && res.hasNextPage()) {
            biz = JstBizUtil.toBiz(new LogisticReq(++page, soIds));
            if (config.isLog()) log.debug("accessToken={},biz={}", accessToken, biz);
            body = JstHolder.getHolder().query(accessToken, url, biz);
            if (config.isLog()) log.debug("body={}", body);
            res = RootRes.toPage(body, LogisticRes.class, "orders");
            if (res != null) list.addAll(res.getDataList());
        }
        return list;
    }

    // 销售订单查询
    public static List<OrderQueryRes> saleOrderQuery(String accessToken, Integer shopId, List<String> soIds, List<Integer> oIds) {
        int page = 1;
        String url = "https://openapi.jushuitan.com/open/orders/single/query";
        // 发货中：Delivering； 已发货：Sent；
        String biz = JstBizUtil.toBiz(new OrderQueryReq(page, shopId, soIds, oIds));
        log.debug("accessToken={},biz={}", accessToken, biz);
        List<OrderQueryRes> list = new ArrayList<>();
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        PageRes<OrderQueryRes> res = RootRes.toPage(body, OrderQueryRes.class, "orders");
        if (res != null) list.addAll(res.getDataList());
        while (res != null && res.hasNextPage()) {
            biz = JstBizUtil.toBiz(new OrderQueryReq(++page, shopId, soIds, oIds));
            log.debug("accessToken={},biz={}", accessToken, biz);
            body = JstHolder.getHolder().query(accessToken, url, biz);
            log.debug("body={}", body);
            res = RootRes.toPage(body, OrderQueryRes.class, "orders");
            if (res != null) list.addAll(res.getDataList());
        }
        return list;
    }

    // 销售订单上传
    public static List<OrderUploadRes> saleOrderUpload(String accessToken, List<OrderUploadReq> reqs) {
        String url = "https://openapi.jushuitan.com/open/jushuitan/orders/upload";
        String biz = JstBizUtil.toListBiz(reqs);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toList(body, OrderUploadRes.class);
    }

    // 销售订单作废
    public static RootRes saleOrderCancel(String accessToken, List<String> oIds, String cancelType) {
        String url = "https://openapi.jushuitan.com/open/jushuitan/orderbyoid/cancel";
        OrderCancelReq req = OrderCancelReq.builder().oIds(oIds).cancelType(cancelType).build();
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.to(body);
    }

    // 物流查询
    public static List<LogisticRes> logisticQuery(String accessToken, List<String> soIds) {
        int page = 1;
        String url = "https://openapi.jushuitan.com/open/logistic/query";
        String biz = JstBizUtil.toBiz(new LogisticReq(page, soIds));
        // log.debug("accessToken={},biz={}", accessToken, biz);
        List<LogisticRes> list = new ArrayList<>();
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        // log.debug("body={}", body);
        PageRes<LogisticRes> res = RootRes.toPage(body, LogisticRes.class, "orders");
        if (res != null) list.addAll(res.getDataList());
        while (res != null && res.hasNextPage()) {
            biz = JstBizUtil.toBiz(new LogisticReq(++page, soIds));
            // log.debug("accessToken={},biz={}", accessToken, biz);
            body = JstHolder.getHolder().query(accessToken, url, biz);
            // log.debug("body={}", body);
            res = RootRes.toPage(body, LogisticRes.class, "orders");
            if (res != null) list.addAll(res.getDataList());
        }
        return list;
    }

    // 采购退货查询
    public static PageRes<PurchaseOutQueryRes> purchaseOutQuery(String accessToken, int page, List<String> soIds) {
        String url = "https://openapi.jushuitan.com/open/purchase/query";
        PurchaseOutQueryReq req = new PurchaseOutQueryReq(page, soIds, "Confirmed");
        String biz = JstBizUtil.toBiz(req);
        return RootRes.toPage(JstHolder.getHolder().query(accessToken, url, biz), PurchaseOutQueryRes.class);
    }

    // 采购退货上传
    public static void purchaseOutUpload(String accessToken) {
        String url = "https://openapi.jushuitan.com/open/jushuitan/purchase/upload";
        PurchaseOutUploadReq req = PurchaseOutUploadReq.builder().supplierId(555).isConfirm(true).externalId("1122")
                .items(CollUtil.toList(PurchaseOutUploadReq.Item.builder().skuId("椰子鸡经典年货版").qty(0)
                        .price(BigDecimal.ZERO).producedDate("2023-10-01").batchId("122").build())).build();
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        PurchaseUploadRes res = RootRes.toBean(JstHolder.getHolder().query(accessToken, url, biz), PurchaseUploadRes.class);
        if (res != null) {
            System.out.println("res=" + res);
        }
    }

    // 采购退货作废
    public static PurchaseCancelRes purchaseOutCancel(String accessToken, List<String> soIds) {
        String url = "https://openapi.jushuitan.com/open/jushuitan/purchaseout/cancel";
        PurchaseOutCancelReq req = PurchaseOutCancelReq.builder().so_ids(soIds).build();
        String biz = JstBizUtil.toBiz(req);
        return RootRes.toBean(JstHolder.getHolder().query(accessToken, url, biz), PurchaseCancelRes.class);
    }

    // 采购单查询
    public static PageRes<PurchaseQueryRes> purchaseQuery(String accessToken, int page, List<String> soIds, List<String> poIds) {
        String url = "https://openapi.jushuitan.com/open/purchase/query";
        PurchaseQueryReq req = new PurchaseQueryReq(page, soIds, poIds);
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toPage(body, PurchaseQueryRes.class);
    }

    // 采购单上传
    public static void purchaseUpload(String accessToken) {
        String url = "https://openapi.jushuitan.com/open/jushuitan/purchase/upload";
        PurchaseUploadReq req = PurchaseUploadReq.builder().supplierId(555).isConfirm(true).externalId("1122")
                .items(CollUtil.toList(PurchaseUploadReq.Item.builder().skuId("椰子鸡经典年货版").qty(0)
                        .price(BigDecimal.ZERO).planArriveDate("2023-10-01").remark("122").build())).build();
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        PurchaseUploadRes res = RootRes.toBean(body, PurchaseUploadRes.class);
        if (res != null) {
            System.out.println("res=" + res);
        }

        biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        PageRes<PurchaseQueryRes> pageRes = RootRes.toPage(body, PurchaseQueryRes.class);
        if (pageRes != null) {
            System.out.println("pageRes=" + pageRes);
        }
    }

    // 采购单作废
    public static PurchaseCancelRes purchaseCancel(String accessToken, List<String> soIds) {
        String url = "https://openapi.jushuitan.com/open/purchase/cancel";
        PurchaseCancelReq req = PurchaseCancelReq.builder().so_ids(soIds).build();
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toBean(body, PurchaseCancelRes.class);
    }

    // 供应商查询
    public static PageRes<SupplierQueryRes> supplierQuery(String accessToken, int page, List<String> supplierCodes) {
        String url = "https://openapi.jushuitan.com/open/supplier/query";
        SupplierQueryReq req = new SupplierQueryReq(page, supplierCodes);
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toPage(body, SupplierQueryRes.class);
    }

    // 仓库查询
    public static List<WmsRes> partnerQuery(String accessToken) {
        int page = 1;
        List<WmsRes> list = new ArrayList<>();
        String url = "https://openapi.jushuitan.com/open/wms/partner/query";
        String biz = new PageReq(page).toBiz();
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        PageRes<WmsRes> res = RootRes.toPage(body, WmsRes.class);
        if (res != null) list.addAll(res.getDataList());
        while (res != null && res.hasNextPage()) {
            biz = new PageReq(++page).toBiz();
            log.debug("accessToken={},biz={}", accessToken, biz);
            body = JstHolder.getHolder().query(accessToken, url, biz);
            log.debug("body={}", body);
            res = RootRes.toPage(body, WmsRes.class);
            if (res != null) list.addAll(res.getDataList());
        }
        return list;
    }

    // 库存查询
    public static PageRes<InventoryQueryRes> inventoryQuery(String accessToken, int page, Integer wmsCoId, Set<String> skuIds) {
        String url = "https://openapi.jushuitan.com/open/inventory/query";
        InventoryQueryReq req = new InventoryQueryReq(page, wmsCoId, String.join(",", skuIds));
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toPage(body, InventoryQueryRes.class, "inventorys");
    }

    // 库存推送
    public static InventoryUploadRes inventoryUpload(String accessToken) {
        // .soId("5555") 必须改变才能成功
        String url = "https://openapi.jushuitan.com/open/jushuitan/inventoryv2/upload";
        InventoryUploadReq req = InventoryUploadReq.builder().soId("5555").isConfirm(true).type("check").remark("测试")
                .warehouse(1).items(CollUtil.toList(InventoryUploadReq.Item.builder().skuId("椰子鸡经典年货版").qty(0).build())).build();
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toBean(body, InventoryUploadRes.class);
    }

    // 商品推送聚水潭后需要查询获取聚水潭的商品编号
    public static PageRes<SkuQueryRes> skuQuery(String accessToken, int page, List<String> skuIds) {
        String url = "https://openapi.jushuitan.com/open/sku/query";
        SkuQueryReq req = new SkuQueryReq(page, String.join(",", skuIds));
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toPage(body, SkuQueryRes.class);
    }

    // 聚水潭的组合商品编号查询
    public static PageRes<SkuQueryRes> combineSkyQuery(String accessToken, int page, List<String> skuIds) {
        String url = "https://openapi.jushuitan.com/open/combine/sku/query";
        SkuQueryReq req = new SkuQueryReq(page, String.join(",", skuIds));
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toPage(body, SkuQueryRes.class);
    }

    // 售后查询
    public static PageRes<ReceivedRes> afterSaleQuery(String accessToken, Date begin, Date end) {
        String url = "https://openapi.jushuitan.com/open/aftersale/received/query";
        String biz = new PageReq(1, DateUtil.formatDateTime(begin), DateUtil.formatDateTime(end)).toBiz();
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toPage(body, ReceivedRes.class);
    }

    // 退货查询
    public static PageRes<RefundRes> refundQuery(String accessToken, Date begin, Date end) {
        String url = "https://openapi.jushuitan.com/open/refund/single/query";
        String biz = new PageReq(1, DateUtil.formatDateTime(begin), DateUtil.formatDateTime(end)).toBiz();
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toPage(body, RefundRes.class);
    }

    // 店铺查询
    public static PageRes<ShopRes> shopQuery(String accessToken, int page, List<String> shopIds) {
        String url = "https://openapi.jushuitan.com/open/shops/query";
        ShopReq req = new ShopReq(page, String.join(",", shopIds));
        String biz = JstBizUtil.toBiz(req);
        log.debug("accessToken={},biz={}", accessToken, biz);
        String body = JstHolder.getHolder().query(accessToken, url, biz);
        log.debug("body={}", body);
        return RootRes.toPage(body, ShopRes.class);
    }
}
